import matplotlib as matplotlib

import numpy as np

import pandas as pd

from pandas import DataFrame, Series

# 可视化显示在界面

# matplotlib inline

import matplotlib

import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来显示中文

plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

# 学习seaborn参考：https://www.jianshu.com/p/c26bc5ccf604


import json

import warnings

warnings.filterwarnings('ignore')

# 设置显示的最大列、宽等参数，消掉打印不完全中间的省略号

# pd.set_option('display.max_columns', 1000)

pd.set_option('display.width', 1000)  # 加了这一行那表格的一行就不会分段出现了

# pd.set_option('display.max_colwidth', 1000)

# pd.set_option('display.height', 1000)

# 显示所有列

pd.set_option('display.max_columns', None)

# 显示所有行

pd.set_option('display.max_rows', None)

movies = pd.read_csv(
    'tmdb_5000_movies.csv',
    encoding='utf_8')

credits = pd.read_csv(
    'tmdb_5000_credits.csv',
    encoding='utf_8')

# 查看信息
# movies.info()

# credits.info()

# 两个数据框都有title列，以及movies.riginal_title

# 以上三个数据列重复，删除两个

del credits['title']

del movies['original_title']

# 连接两个csv文件

merged = pd.merge(movies, credits, left_on='id', right_on='movie_id', how='left')

# 删除不需要分析的列

df = merged.drop(['homepage', 'overview', 'spoken_languages', 'status', 'tagline', 'movie_id'], axis=1)

# 显示
# df.info()

# 2 缺失值处理
# 查找缺失值记录-release_date
df[df.release_date.isnull()]
# print(df[df.release_date.isnull()])

# 查找缺失值记录-runtime
df[df.runtime.isnull()]
# print(df[df.runtime.isnull()])

# 3 重复值处理
len(df.id.unique())
# print(len(df.id.unique()))

# 4 日期值处理
df['release_year'] = pd.to_datetime(df.release_date, format = '%Y-%m-%d',errors='coerce').dt.year
df['release_month'] = pd.to_datetime(df.release_date).apply(lambda x: x.month)
df['release_day'] = pd.to_datetime(df.release_date).apply(lambda x: x.day)

# 显示处理后的日期
# i = 0
# for i in range(0, df['release_day'].size):
#     print(str(df['release_year'][i]).rstrip('.0') + '-' + str(df['release_month'][i]).rstrip('.0')
#     + '-' + str(df['release_day'][i]).rstrip('.0'))
#     i = i + 1

# 筛选数据
df.describe()
# print(df.describe())

df = df[(df.vote_count >= 50) & (df.budget * df.revenue * df.popularity * df.vote_average != 0)].reset_index(drop='True')

# 6 json 数据转换
json_column = ['genres', 'keywords', 'production_companies', 'production_countries', 'cast', 'crew']

# 1-json本身为字符串类型，先转换为字典列表

for i in json_column:
    df[i] = df[i].apply(json.loads)


# 提取name

# 2-将字典列表转换为以','分割的字符串

def get_name(x):
    return ','.join([i['name'] for i in x])


df['cast'] = df['cast'].apply(get_name)


# 提取derector

def get_director(x):
    for i in x:

        if i['job'] == 'Director':
            return i['name']


df['crew'] = df['crew'].apply(get_director)

for j in json_column[0:4]:
    df[j] = df[j].apply(get_name)

# 重命名

rename_dict = {'cast': 'actor', 'crew': 'director'}

df.rename(columns=rename_dict, inplace=True)

df.info()

df.head(5)

# 7 数据备份
# 备份原始数据框original_df

org_df = df.copy()

df.reset_index().to_csv("TMDB_5000_Movie_Dataset_Cleaned.csv")


# 想要探索影响票房的因素，从电影市场趋势，观众喜好类型，电影导演，发行时间，评分与关键词等维度着手，给从业者提供合适的建议。

# 定义一个集合，获取所有的电影类型

genre = set()

for i in df['genres'].str.split(','):  # 去掉字符串之间的分隔符，得到单个电影类型
    genre = set().union(i, genre)  # 集合求并集

    # genre.update(i) #或者使用update方法

genre.discard('')  # 去除多余的元素

print(genre)

# 将genre转变成列表

genre_list = list(genre)

# 创建数据框-电影类型

genre_df = pd.DataFrame()

# 对电影类型进行one-hot编码

for i in genre_list:
    # 如果包含类型 i，则编码为1，否则编码为0

    genre_df[i] = df['genres'].str.contains(i).apply(lambda x: 1 if x else 0)

# 将数据框的索引变为年份

genre_df.index = df['release_year']

genre_df.head(5)

# print(genre_df)

# 电影类型数量（绘制条形图）
# 计算得到每种类型的电影总数目，并降序排列

grnre_sum = genre_df.sum().sort_values(ascending=False)

# 可视化


colors = ['tomato', 'C0']

plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来显示中文

grnre_sum.plot(kind='bar', label='genres', color=colors, figsize=(12, 9))

plt.title('不同类型的电影数量总计', fontsize=20)

plt.xticks(rotation=60)

plt.xlabel('电影类型', fontsize=16)

plt.ylabel('数量', fontsize=16)

plt.grid(False)

plt.savefig("不同电影类型数量-条形图.png", dpi=300)  # 在 plt.show() 之前调用 plt.savefig()

plt.show()

# 电影类型占比（绘制饼图）
gen_shares = grnre_sum / grnre_sum.sum()

# 设置other类，当电影类型所占比例小于%1时，全部归到other类中

others = 0.01

gen_pie = gen_shares[gen_shares >= others]

gen_pie['others'] = gen_shares[gen_shares < others].sum()

colors = ['tomato', 'lightskyblue', 'goldenrod', 'wheat', 'y', 'tomato', 'lightskyblue', 'goldenrod', 'wheat', 'y',
          'tomato', 'lightskyblue', 'goldenrod', 'wheat', 'y', 'tomato', 'lightskyblue', 'goldenrod', 'wheat', 'y',
          'lightskyblue']

# 设置分裂属性

# 所占比例小于或等于%2时，增大每块饼片边缘偏离半径的百分比

explode = (gen_pie <= 0.02) / 10

# 绘制饼图

gen_pie.plot(kind='pie', label='', colors=colors, explode=explode, startangle=0,

             shadow=False, autopct='%3.1f%%', figsize=(8, 8))

plt.title('不同电影类型所占百分比', fontsize=20)

plt.savefig("不同电影类型所占百分比-饼图.png", dpi=300)